package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSkuVo;
import com.spzx.product.api.domain.SkuPriceVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class ICartServiceImpl implements ICartService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RemoteProductService remoteProductService;

    @Override
    public void addToCart(Long skuId, Integer skuNum) {

        // 获取当前登录用户的id
        Long userId = SecurityUtils.getUserId();
        //构建“用户”购物车hash结构key  order:cart:用户ID
        String cartKey = getCartKey();
        //创建Hash结构绑定操作对象（方便对hash进行操作）
        String hashKey = skuId.toString();
        Integer threshold = 5;
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        //说明该商品在购物车中已有，对数量进行累加 ，不能超过指定上限
        if (hashOps.hasKey(hashKey)) {
            CartInfo cartInfo = hashOps.get(hashKey);
            int totalCount = cartInfo.getSkuNum() + skuNum;
            if (totalCount > threshold) {
                throw new ServiceException("已达商品数量上限");
            }
//            cartInfo.setSkuNum(totalCount > threshold ? threshold : totalCount);
            cartInfo.setSkuNum(totalCount);
            hashOps.put(hashKey, cartInfo);
        } else {
            //添加的商品总类不超过一定数量
            Long count = hashOps.size();
            if (count >= 3) {
                throw new RuntimeException("商品种类数量超过上限！");
            }
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);
            //初次加入数量最大值
            cartInfo.setSkuNum(skuNum > threshold ? threshold : skuNum);
            //远程调用商品服务获取商品sku基本信息
            R<ProductSkuVo> productSkuVo = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if (R.FAIL == productSkuVo.getCode()) {
                //远程调用失败
                throw new ServiceException(productSkuVo.getMsg());
            }
            ProductSkuVo productSku = productSkuVo.getData();
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setSkuPrice(productSku.getSalePrice());
            cartInfo.setCreateTime(new Date());
            //将购物车商品存入Redis
            hashOps.put(hashKey, cartInfo);
        }
    }

    @Override
    public List<CartInfo> getCartList() {
//        String cartKey = getCartKey(SecurityUtils.getUserId());
        String cartKey = getCartKey();
//        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
//        List<CartInfo> cartInfoList = hashOps.values();
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(cartKey);
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            return cartInfoList.stream().sorted(((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    @Override
    public void deleteCart(Long skuId) {
        String cartKey = getCartKey();
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        hashOps.delete(skuId.toString());
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        String cartKey = getCartKey();
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        if (hashOps.hasKey(skuId.toString())) {
            CartInfo cartInfo = hashOps.get(skuId.toString());
            if (cartInfo != null) {
                cartInfo.setIsChecked(isChecked);
                hashOps.put(skuId.toString(), cartInfo);
            }
        }
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        String cartKey = getCartKey();
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
//        if (!CollectionUtils.isEmpty(cartInfoList)) {
//             cartInfoList.stream().map(cartInfo -> {
//                        CartInfo cartInfo1 = hashOps.get(cartInfo.getSkuId().toString());
//                         cartInfoNew.setIsChecked(isChecked);
//                         hashOps.put(cartInfo.getSkuId().toString(),cartInfo1);
//                         return cartInfoNew;
//                    }
//            ).collect(Collectors.toList());
//        }
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList.forEach(cartInfo -> {
                CartInfo cartInfoNew = hashOps.get(cartInfo.getSkuId().toString());
                if (cartInfoNew != null) {
                    cartInfoNew.setIsChecked(isChecked);
                    hashOps.put(cartInfo.getSkuId().toString(), cartInfoNew);
                }
            });
        }
    }

    @Override
    public void clearCart() {
        String cartKey = getCartKey();
        redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfo> getCartCheckedList() {
        // todo 获取购物车中选中商品sku
        String cartKey = this.getCartKey();
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList = cartInfoList.stream()
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .collect(Collectors.toList());
        }
        return cartInfoList;
    }

    @Override
    public Boolean updateCartPrice(Long userId) {
        // todo 更新用户购物车列表价格
        String cartKey = getCartKey();
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList.stream()
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .peek(cartInfo -> {
                        R<SkuPriceVo> skuPriceResult = remoteProductService.getSkuPrice(cartInfo.getSkuId(), SecurityConstants.INNER);
                        if (R.FAIL == skuPriceResult.getCode()){
                            throw new ServiceException(skuPriceResult.getMsg());
                        }
                        SkuPriceVo skuPriceVo =skuPriceResult.getData();
                                cartInfo.setSkuPrice(skuPriceVo.getSalePrice());
                                hashOps.put(cartInfo.getSkuId().toString(), cartInfo);
                            }
                    ).collect(Collectors.toList());
        }
        return true;
    }

    @Override
    public Boolean deleteCartCheckedList(Long userId) {
        // todo 删除用户购物车列表中选中商品列表
        String cartKey = getCartKey();
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartCachInfoList = hashOps.values();
        if (!CollectionUtils.isEmpty(cartCachInfoList)){
            cartCachInfoList.stream()
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .peek(cartInfo -> hashOps.delete(cartInfo.getSkuId().toString()))
                    .collect(Collectors.toList());
        }
        return true;
    }

    private String getCartKey() {
        // todo 定义key order:userId:cart
        return "order:cart:" + SecurityUtils.getUserId();
    }
}
